<!--
 * @Description: 用户信息
 * @Author: xinqiao lxq1990.0716@qq.com
 * @Date: 2024-04-19
 * @LastEditors: xinqiao lxq1990.0716@qq.com
 * @LastEditTime: 2024-04-24
-->
<script lang="ts" setup>
  import { computed, ref } from 'vue'

  import { requestAccountAuthPhone, requestUnBind } from '@/api/system/ysys-user/account'
  import { requestUpdateUserInfoByUserId } from '@/api/system/ysys-user/user'
  import { UserSexDesc } from '@/api/system/ysys-user/user/enum'
  import { HttpCodeEnum } from '@/enum/httpEnum'
  import { myPng } from '@/enum/imageEnum'
  import env from '@/env/index'
  import { useUserInfoStore } from '@/stores/userInfo'
  import { saveUserInfo } from '@/utils/auth'
  import { getUserId } from '@/utils/storage'
  import { getToken } from '@/utils/storage'
  /** 用户信息 */
  const userInfoStore = useUserInfoStore()
  const userInfo = ref({ headImg: userInfoStore.headImg })

  /** 昵称 */
  const nickname = computed(() => userInfoStore.userName ?? '游客')

  /** 昵称是否聚焦 */
  const nicknameFocus = ref(false)

  /** 聚焦昵称 */
  const focusNickname = () => (nicknameFocus.value = true)

  /** 失焦昵称 */
  const blurNickname = () => (nicknameFocus.value = false)

  const changeNickname = async (e: any) => {
    const userName = e.detail.value
    await requestUpdateUserInfoByUserId({ userId: getUserId(), userName })
    saveUserInfo()
  }

  /** picker选项内容 */
  const pickerRanges = Object.entries(UserSexDesc).map((item) => ({ label: item[1], value: parseInt(item[0]) }))

  /** picker选中项-索引 */
  const getPickerIndex = computed(() => pickerRanges.findIndex((item) => item.value === userInfoStore.userSex))

  /** picker切换选项 */
  const onPickerChange = async (e: WechatMiniprogram.PickerChange) => {
    const userSex = parseInt(e.detail.value as string)
    await requestUpdateUserInfoByUserId({ userId: getUserId(), userSex })
    saveUserInfo()
  }

  /**
   * 退出登录
   */
  const logout = async () => {
    const res = await requestUnBind({ userId: getUserId() })
    console.log('logout: ', res) //TODO
  }

  const uploadFile = (avatarUrl: string) => {
    return new Promise((resolve) => {
      wx.showLoading({
        title: '图片上传中',
      })
      wx.uploadFile({
        url: `${env.api}/contentFile/upload/V1`,
        filePath: avatarUrl,
        name: 'file',
        header: { Authorization: getToken() },
        success(res: any) {
          const data = JSON.parse(res.data)
          if (data.responseCode === HttpCodeEnum.SUCCESS) {
            userInfo.value.headImg = data.responseData
            resolve(data.responseData)
          } else {
            uni.showToast({ title: data.responseMessage || '上传图片失败', icon: 'none' })
          }
        },
        fail(err) {
          console.log('uploadFile fail: ', err)
        },
        complete() {
          wx.hideLoading()
        },
      })
    })
  }
  const onChooseAvatar = (e: any) => {
    console.log('onChooseAvatar: ', e.detail.avatarUrl)
    uploadFile(e.detail.avatarUrl).then(async () => {
      await requestUpdateUserInfoByUserId({ userId: getUserId(), headImg: userInfo.value.headImg })
      saveUserInfo()
    })
  }
  const getPhoneNumber = async (e: any) => {
    const { responseCode, responseData } = await requestAccountAuthPhone({ wxCode: e.detail.code })
    if (responseCode === HttpCodeEnum.SUCCESS) {
      userInfoStore.phone = responseData as string
    }
  }
</script>

<template>
  <view class="userInfo">
    <view class="avatar">
      <text class="avatar-label">头像</text>
      <button class="avatar-img" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
        <image class="img" mode="widthFix" :src="userInfo.headImg" />
      </button>
      <image class="avatar-arrow" :src="myPng.arrowRight" />
    </view>
    <view class="nickname">
      <text class="nickname-label">昵称</text>
      <input
        type="nickname"
        class="nickname-value"
        :class="nicknameFocus ? 'focus' : ''"
        v-model="nickname"
        @change="(e) => changeNickname(e)"
        @focus="focusNickname"
        @blur="blurNickname"
      />
      <image class="nickname-arrow" :src="myPng.arrowRight" />
    </view>
    <view class="sex">
      <text class="sex-label">性别</text>
      <picker @change="onPickerChange" :value="getPickerIndex" :range="pickerRanges" range-key="label">
        <view class="sex-value">{{ UserSexDesc[userInfoStore.userSex] ?? '未知' }}</view>
      </picker>
      <image class="sex-arrow" :src="myPng.arrowRight" />
    </view>
    <view class="phone">
      <text class="phone-label">手机号</text>
      <button class="phone-value" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">
        <text>{{ userInfoStore.phone }}</text>
        <image class="phone-arrow" :src="myPng.arrowRight" />
      </button>
    </view>
    <view style="display: none" class="logout" @click="logout()">退出登录</view>
  </view>
</template>

<style lang="less">
  .userInfo {
    padding-top: 32rpx;
  }

  .avatar {
    position: relative;
    width: 686rpx;
    height: 176rpx;
    margin: auto;
    background: #fff;
    border-radius: 32rpx;

    .avatar-label {
      position: absolute;
      top: 64rpx;
      left: 32rpx;
      font-size: 32rpx;
      line-height: 48rpx;
      color: #1d2129;
    }

    .avatar-img {
      position: absolute;
      top: 32rpx;
      right: 0;
      z-index: 2;
      width: calc(100% - 100rpx);
      height: 112rpx;
      background: transparent;

      .img {
        position: absolute;
        right: 80rpx;
        width: 112rpx;
        border-radius: 50%;

      }
    }

    .avatar-arrow {
      position: absolute;
      top: 72rpx;
      right: 32rpx;
      width: 20rpx;
      height: 32rpx;
    }
  }

  .nickname {
    position: relative;
    width: 686rpx;
    height: 112rpx;
    margin: auto;
    margin-top: 32rpx;
    background: #fff;
    border-top-left-radius: 32rpx;
    border-top-right-radius: 32rpx;

    .nickname-label {
      position: absolute;
      top: 32rpx;
      left: 32rpx;
      font-size: 32rpx;
      line-height: 48rpx;
      color: #1d2129;
    }

    .nickname-value {
      position: absolute;
      top: 24rpx;
      right: 0;
      width: calc(100% - 100rpx);
      height: 64rpx;
      padding-right: 80rpx;
      font-size: 32rpx;
      line-height: 64rpx;
      color: #4e5969;
      text-align: right;
      border-radius: 10rpx;

      &.focus {
        border: 1px solid #ddd;
      }
    }

    .nickname-arrow {
      position: absolute;
      top: 40rpx;
      right: 32rpx;
      width: 20rpx;
      height: 32rpx;
    }
  }

  .sex {
    position: relative;
    width: 686rpx;
    height: 112rpx;
    margin: auto;
    background: #fff;
    border-bottom-right-radius: 32rpx;
    border-bottom-left-radius: 32rpx;

    .sex-label {
      position: absolute;
      top: 32rpx;
      left: 32rpx;
      font-size: 32rpx;
      line-height: 48rpx;
      color: #1d2129;
    }

    .sex-value {
      position: absolute;
      top: 32rpx;
      right: 80rpx;
      width: calc(100% - 100rpx);
      font-size: 32rpx;
      line-height: 48rpx;
      color: #4e5969;
      text-align: right;
    }

    .sex-arrow {
      position: absolute;
      top: 40rpx;
      right: 32rpx;
      width: 20rpx;
      height: 32rpx;
    }
  }

  .phone {
    position: relative;
    width: 686rpx;
    height: 112rpx;
    margin: 32rpx auto 0;
    background: #fff;
    border-radius: 32rpx;

    .phone-label {
      position: absolute;
      top: 32rpx;
      left: 32rpx;
      font-size: 32rpx;
      line-height: 48rpx;
      color: #1d2129;
    }

    .phone-value {
      position: absolute;
      top: 32rpx;
      right: 0;
      width: calc(100% - 100rpx);
      font-size: 32rpx;
      line-height: 48rpx;
      color: #4e5969;
      text-align: right;
      background: transparent;

      text {
        margin-right: 50rpx;
      }
    }

    .phone-arrow {
      position: absolute;
      top: 10rpx;
      right: 32rpx;
      width: 20rpx;
      height: 32rpx;
    }
  }
</style>
